/**
 * Copyright (c) 2023 - present All rights reserved.
 * <p>
 * Reprinted has been protected by the copyright laws.
 */

package cn.myxl.smart.devkit.commit.configuration;

import cn.myxl.smart.devkit.commit.model.CommitType;
import cn.myxl.smart.devkit.commit.model.CommitTypeTableModel;
import cn.myxl.smart.devkit.commit.model.SettingState;
import cn.myxl.smart.devkit.commit.persistent.HelperSetting;
import cn.myxl.smart.devkit.core.util.SMDUtil;
import com.intellij.ui.JBColor;
import com.intellij.ui.table.JBTable;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author zhangyang
 * @date 2023-11-14 14:22
 */

@Slf4j
public class CommitTypeTable extends JBTable {
	private final CommitTypeTableModel tableModel;
	private final List<CommitType> typeAliases;
	private final SettingState settingState;

	public CommitTypeTable(SettingState settingState) {
		this.settingState = settingState;

		this.typeAliases = SMDUtil.clone(settingState.getTypeAliases());

		this.tableModel = new CommitTypeTableModel(this.typeAliases);

		setModel(tableModel);

		TableColumn nameColumn = getColumnModel().getColumn(0);
		TableColumn valueColumn = getColumnModel().getColumn(1);

		nameColumn.setCellRenderer(new DefaultTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				final String macroValue = getAliasValueAt(row);
				component.setForeground(macroValue.isEmpty() ? JBColor.RED : isSelected ? table.getSelectionForeground() : table.getForeground());
				return component;
			}
		});

		setColumnSize(nameColumn, 150, 250, 150);
		setColumnSize(valueColumn, 550, 750, 550);
		setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	}

	private void setColumnSize(TableColumn column, int preferredWidth, int maxWidth, int minWidth) {
		column.setPreferredWidth(preferredWidth);
		column.setMaxWidth(maxWidth);
		column.setMinWidth(minWidth);
	}

	private String getAliasValueAt(int row) {
		return (String) getValueAt(row, 1);
	}

	private boolean isValidRow(int selectedRow) {
		return selectedRow >= 0 && selectedRow < typeAliases.size();
	}

	private int indexOfAliasWithName(String name) {
		return typeAliases.stream().filter(item -> item.getTitle().equals(name)).findFirst().map(item -> typeAliases.indexOf(item)).orElse(-1);
	}

	public void handleAddAction() {
		CommitTypeEditorUI typeEditor = new CommitTypeEditorUI("Add Type");

		if (typeEditor.showAndGet()) {
			String name = typeEditor.getTitle();
			typeAliases.add(new CommitType(typeEditor.getTitle(), typeEditor.getDescription()));
			int index = indexOfAliasWithName(name);
			tableModel.fireTableDataChanged();
			setRowSelectionInterval(index, index);
		}

	}

	public void handleRemoveAction() {
		System.out.println("handleRemoveAction");

		int[] selectedRows = getSelectedRows();

		if (selectedRows.length == 0) return;

		Arrays.sort(selectedRows);

		for (int i = selectedRows.length - 1; i >= 0; i--) {
			final int selectedRow = selectedRows[i];
			if (isValidRow(selectedRow)) {
				typeAliases.remove(selectedRow);
			}
		}

		tableModel.fireTableDataChanged();
	}

	public boolean handleEditAction() {
		if (getSelectedRowCount() != 1) {
			return false;
		}

		int selectedRow = getSelectedRow();

		CommitType commitType = typeAliases.get(selectedRow);

		CommitTypeEditorUI typeEditor = new CommitTypeEditorUI("Edit Type", commitType);

		if (typeEditor.showAndGet()) {
			commitType.setTitle(typeEditor.getTitle());
			commitType.setDescription(typeEditor.getDescription());

			tableModel.fireTableDataChanged();
		}

		return true;
	}

	public void handleMoveDownAction() {
		int selectedRow = getSelectedRow();

		int index = selectedRow + 1;

		if (selectedRow != -1) {
			Collections.swap(typeAliases, selectedRow, index);
		}

		setRowSelectionInterval(index, index);
	}

	public void handleMoveUpAction() {
		int selectedRow = getSelectedRow();

		int index = selectedRow - 1;

		if (selectedRow != -1) {
			Collections.swap(typeAliases, selectedRow, index);
		}
		setRowSelectionInterval(index, index);
	}

	public void reset() {
		typeAliases.clear();
		typeAliases.addAll(SMDUtil.clone(settingState.getTypeAliases()));
		tableModel.fireTableDataChanged();
	}

	public boolean isModified() {
		return !settingState.getTypeAliases().equals(typeAliases);
	}

	public List<CommitType> applyTypeAliases() {
		settingState.setTypeAliases(typeAliases);

		return typeAliases;
	}

}
